iT邦幫忙

2026 iThome 鐵人賽

DAY 1
1

前言

這個系列是我準備 CKA 時整理下來的 Kubernetes 筆記,內容會從基礎資源一路寫到排程、儲存、網路與 Pod 分散機制,也會搭配實際操作與 YAML 範例。

第一天先從建立叢集開始。

這次使用 kubeadm 在 GCP Compute Engine 上建立一套 Kubernetes 叢集,架構為 1 個 Control Plane 與 2 個 Worker Node,作業系統使用 Debian。

文章會記錄 Container Runtime、kubeadm、kubelet、kubectl、CNI 的安裝流程,以及 Worker Node 如何加入叢集。最後會部署一個 Nginx,確認整個叢集可以正常運作。

這篇主要是完整記錄一次 kubeadm 的建置流程,方便之後重建環境或準備 CKA 時快速複習。

接下來的文章會依序整理 Pod、Deployment、Service、Ingress、ConfigMap、Secret、Storage、Scheduler 與其他 Kubernetes 常用功能。


環境準備

本教學使用三台 VM 節點(1 個 master 節點、2 個 worker 節點),部署於 GCP Compute Engine,作業系統為 Debian。

https://ithelp.ithome.com.tw/upload/images/20260803/20181928UQh8hkd2uu.png

系統需求:

  • 作業系統:Debian 12(Bookworm)或 Ubuntu 20.04+
  • CPU:至少 2 核心
  • 記憶體:至少 2GB RAM
  • 網路:各節點之間可互相通訊
  • 權限:sudo 或 root 權限

步驟一:在所有節點上安裝容器運行時(Container Runtime)

執行節點:master + node1 + node2(三台都要做)

1.1 關閉 Swap

https://ithelp.ithome.com.tw/upload/images/20260803/20181928l0dqnZxm6y.png

Kubernetes 要求關閉 swap 才能正常運作:

# 暫時關閉 swap(重開機後會恢復)
sudo swapoff -a

# 永久關閉 swap(編輯 /etc/fstab)
sudo sed -i '/ swap / s/^/#/' /etc/fstab

# 驗證 swap 已關閉(應該顯示全部為 0)
free -h

重要: 如果不關閉 swap,kubelet 將無法啟動,導致節點無法加入叢集。

說明:

kubelet 需要可預期的記憶體管理行為,若啟用 swap,將導致資源計算與 OOM 行為不可預期。

1.2 設定系統參數

# 載入必要的核心模組
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# 設定必要的 sysctl 參數
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 套用 sysctl 參數
sudo sysctl --system

1.3 安裝 containerd

# 更新套件列表
sudo apt-get update

# 安裝必要的套件
sudo apt-get install -y ca-certificates curl gnupg

# 安裝 containerd
sudo apt-get install -y containerd

# 產生預設設定檔
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# 修改設定檔,啟用 SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml

# 重啟 containerd
sudo systemctl restart containerd
sudo systemctl enable containerd

說明:

Kubernetes 自 v1.24 起預設使用 systemd 作為 cgroup driver,containerd 必須同步設定為 SystemdCgroup,否則 kubelet 可能無法正常啟動。

1.4 設定防火牆(可選)

注意:

如果你的環境使用 GCP、AWS 等雲端平台,可能還需要在雲端安全群組(Security Group)或防火牆規則中開放相應端口。

選項 A:關閉防火牆(適合測試環境)

# 關閉 ufw 防火牆
sudo ufw disable

# 檢查防火牆狀態
sudo ufw status

選項 B:開放必要端口(適合生產環境)

# Master 節點需要開放的端口
sudo ufw allow 6443/tcp    # Kubernetes API server
sudo ufw allow 2379:2380/tcp  # etcd server client API
sudo ufw allow 10250/tcp   # Kubelet API
sudo ufw allow 10259/tcp   # kube-scheduler
sudo ufw allow 10257/tcp   # kube-controller-manager

# Worker 節點需要開放的端口
sudo ufw allow 10250/tcp   # Kubelet API
sudo ufw allow 30000:32767/tcp  # NodePort Services

# Calico 需要開放的端口
sudo ufw allow 179/tcp     # BGP
sudo ufw allow 4789/udp    # VXLAN

# 啟用防火牆
sudo ufw enable

# 檢查防火牆狀態
sudo ufw status

說明:

本教學使用 GCP Compute Engine,預設防火牆規則已允許內網通訊。若你的環境有啟用 ufw,建議在測試階段關閉防火牆,待叢集穩定後再開啟並設定相應規則。

Debian 預設未安裝 ufw,若需要請先執行 sudo apt install ufw


步驟二:在所有節點上安裝 kubeadm、kubelet 和 kubectl

執行節點:master + node1 + node2(三台都要做)

本節提供兩種安裝方式,請依你的學習目標選擇:

  • 若你只是想快速建立一個可用的 Kubernetes 環境,可直接安裝最新版。
  • 若你希望在後續章節練習 Kubernetes 升版流程,建議安裝比最新版低一個 minor version。

2.1 新增 Kubernetes apt repository

# 更新套件索引並安裝必要工具
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

# 建立 keyrings 目錄
sudo mkdir -p /etc/apt/keyrings

# 下載 Kubernetes 的 GPG 金鑰
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list 

版本說明:

上述指令使用 v1.34 版本。若要使用其他版本(如 v1.30、v1.31),請將 URL 中的 v1.34 改為對應版本號。

注意:

後續安裝 kubeadm、kubelet 和 kubectl 後,請務必使用 apt-mark hold 鎖定版本,避免系統自動升級導致版本不一致,影響叢集穩定性。

2.2 安裝 kubelet、kubeadm 和 kubectl

版本選擇建議:

如果你計畫練習 Kubernetes 升版操作,建議安裝比最新版低一個 minor version。本教學的 apt repo 設定為 v1.34,因此下方選項 B 會安裝 v1.34.0,後續可練習升級到 v1.35。

選項 A:安裝最新版本

# 更新套件列表
sudo apt-get update

# 安裝最新版本
sudo apt-get install -y kubelet kubeadm kubectl

# 鎖定版本,防止自動更新
sudo apt-mark hold kubelet kubeadm kubectl

# 啟用 kubelet 服務
sudo systemctl enable --now kubelet

選項 B:安裝特定版本(推薦用於練習升版)

# 查看可用的版本
apt-cache madison kubeadm

# 範例:安裝 v1.34.x(作為後續升級到 v1.35 的起點)
# 請根據上面的輸出選擇你要的版本號
VERSION="1.34.0-1.1"
sudo apt-get install -y kubelet=$VERSION kubeadm=$VERSION kubectl=$VERSION

# 鎖定版本,防止自動更新
sudo apt-mark hold kubelet kubeadm kubectl

# 啟用 kubelet 服務
sudo systemctl enable --now kubelet

# 驗證安裝的版本
kubeadm version
kubectl version --client

版本號說明:

  • 版本格式通常是 1.34.0-1.1
  • 其中 1.34.0 是 Kubernetes 版本
  • -1.1 是套件版本
  • 三個元件(kubelet、kubeadm、kubectl)必須使用相同版本

步驟三:初始化 Master 節點

執行節點:僅在 master 上執行

3.1 在 Master 節點上執行初始化

# 初始化 Kubernetes cluster
sudo kubeadm init --kubernetes-version=v1.34.0 --pod-network-cidr=192.168.0.0/16

參數說明:

  • --kubernetes-version=v1.34.0:明確指定 Kubernetes 版本,確保所有節點版本一致
  • --pod-network-cidr=192.168.0.0/16:Pod 網路 CIDR,此設定與 Calico 預設 IP Pool 相符

重要提示:

初始化完成後,會顯示一段 kubeadm join 指令,請務必保存這段指令,稍後會用來將 Worker 節點加入叢集。

3.2 設定 kubectl 權限

# 為當前使用者設定 kubeconfig
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

3.3 驗證 Master 節點狀態

https://ithelp.ithome.com.tw/upload/images/20260803/20181928gaDz2Osme0.png

# 查看節點狀態
kubectl get nodes

# 查看系統 Pods
kubectl get pods -n kube-system

說明:

在尚未安裝 CNI 前:

  • 節點狀態可能顯示為 NotReady
  • CoreDNS Pod 可能處於 Pending

這屬於正常現象,會在後續安裝 CNI 後恢復正常。


步驟四:安裝網路插件(CNI)

執行節點:僅在 master 上執行

這裡使用 Calico 作為網路插件:

# 安裝 Calico v3.28.0
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml

注意:

本教學使用 Calico,其預設 IP Pool 為 192.168.0.0/16,與 kubeadm init 的 --pod-network-cidr 參數一致。若要使用其他 CNI 插件(如 Flannel),需要將 --pod-network-cidr 改為該 CNI 的預設 CIDR(Flannel 為 10.244.0.0/16)。

4.1 觀察 Calico Pod 部署狀態

# 查看 kube-system 中的 Calico、CoreDNS 與 kube-proxy
kubectl get pods -n kube-system | egrep 'calico|coredns|kube-proxy'

# 注意:有些 Calico 安裝方式會使用獨立的 calico-system namespace,若你的環境使用該 namespace,則改查:
# kubectl get pods -n calico-system

# 即時觀察 Pod 啟動過程(可選,按 Ctrl + C 停止監看)
kubectl get pods -n kube-system -w

預期結果:

  • calico-node Pod 會在每個節點上以 DaemonSet 形式啟動
  • Master 節點狀態將由 NotReady 變為 Ready
  • CoreDNS Pod 將由 Pending 變為 Running

4.2 驗證網路插件安裝

# 檢查節點狀態
kubectl get nodes

# 檢查系統 Pod 狀態
kubectl get pods -n kube-system

Calico、CoreDNS、kube-proxy 皆為 Running,且節點狀態為 Ready,代表 Pod 網路已成功建立。


步驟五:將 Worker 節點加入叢集

執行節點:僅在 node1 + node2 上執行

5.1 在 Worker 節點上執行 join 指令

在 node1 和 node2 上執行之前保存的 kubeadm join 指令:

sudo kubeadm join <master-ip>:6443 --token <token> \
    --discovery-token-ca-cert-hash sha256:<hash>

如果忘記 join 指令:

可以在 Master 節點上重新產生:

kubeadm token create --print-join-command

5.2 在 Master 節點上驗證

# 查看所有節點
kubectl get nodes

應該會看到類似輸出:

https://ithelp.ithome.com.tw/upload/images/20260803/201819287Dg0V5J9nT.png


步驟六:驗證叢集運作

執行節點:在 master 上執行

6.1 部署測試應用

# 建立測試 Deployment
kubectl create deployment nginx --image=nginx

# 暴露服務
kubectl expose deployment nginx --port=80 --type=NodePort

# 查看服務
kubectl get svc nginx

# 查看 Pod 狀態與分佈
kubectl get pod -o wide

說明:

使用 -o wide 可以看到 Pod 被排程到哪個節點。Kubernetes 會根據資源可用性將 Pod 排程到任一 Worker 節點。

6.2 測試訪問

# 取得 NodePort
NODE_PORT=$(kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}')

# 使用任一節點 IP 測試
# <node-ip> 可使用任一 Worker 節點的內部 IP(同網段測試)或外部 IP(需防火牆放行)
curl http://<node-ip>:$NODE_PORT

若成功連線,應可看到 Nginx 預設的 Welcome Page。

https://ithelp.ithome.com.tw/upload/images/20260803/201819286GQwj8VxID.png

注意:

若無法從外部連線 NodePort,請確認雲端防火牆已放行 30000–32767/tcp。


參考資源


小結

今天我們完成了使用 kubeadm 從零開始建立一個 Kubernetes 叢集,包含:

  • 設定容器運行時(containerd)

  • 安裝 kubeadm、kubelet 和 kubectl

  • 初始化 Master 節點

  • 安裝網路插件(Calico)

  • 將 Worker 節點加入叢集

  • 驗證叢集運作

這是一個基礎但完整的 K8s 叢集,後續我們會在這座叢集上持續探索更多 Kubernetes 的核心資源。

明天我們會從部署第一個 Pod 開始,認識 Pod 與 Deployment 的差異,搞懂為什麼你幾乎不會單獨建 Pod。敬請期待!


下一篇
Day 02|Pod 與 Deployment — 從「一次性容器」到「自動維運」
系列文
從零到 CKA:30 天掌握 Kubernetes 核心觀念與實作2
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言